<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>2_react生命周期(旧)</title>
</head>

<body>
  <!-- 准备好一个“容器” -->
  <div id="test"></div>
  <!-- 引入react核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom 用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel 用于将jsx转换为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>

  <script type="text/babel">  // 此处一定要写babel

    /*
    1.初始化阶段:由ReactDOM.render()触发---初次渲染
        1.constructor()
        2.componentWillMount()
        3.render()
        4.componentDidMount() ===> 常用
                              一般在这个钩子中做一些初始化的事，例如：开启定时器、发生网络请求、订阅消息
    2.更新阶段:由组件内部this.setSate()或父组件重新render触发
        1.shouldComponentUpdate()
        2.componentWillUpdate()
        3.render() ===> 必须使用的一个
        4.componentDidUpdate()
    3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
        1.componentWillUnmount()  ===> 常用
                                 一般在这个钩子中做一些收尾的事，例如：关闭定时器、取消订阅消息
    
    */

    // 1. 创建组件
    class Life extends React.Component {

      constructor(props) {
        super(props)
        console.log('Life---constructor')
        // 初始化状态
        this.state = { count: 10 }
      }

      // 加1按钮回调
      add = () => {
        // 获取原生状态
        const { count } = this.state
        // 更新状态
        this.setState({ count: count + 1 })
      }
      // 卸载组件按钮的回调
      death = () => {
        // 卸载组件
        ReactDOM.unmountComponentAtNode(document.getElementById('test'))
      }

      //强制更新按钮的回调
      force = () => {
         this.forceUpdate()
      }

      // 组件将要挂载的钩子
      UNSAFE_componentWillMount() {
        console.log('Life---componentWillMount')
      }
      // 组件挂载完毕的钩子
      componentDidMount() {
        console.log('Life---componentDidMount')
      }


      //组件将要卸载的钩子
      componentWillUnmount() {
        console.log('Life---componentWillUnmount')

      }
      //控制组件更新的“阀门”
      shouldComponentUpdate() {
        console.log('Life---shouldComponentUpdate')
        return true
      }

      // 组件将要更新的钩子
      UNSAFE_componentWillUpdate() {
        console.log('Life---componentWillUpdate')
      }
      // 组件更新完毕的钩子
      componentDidUpdate() {
        console.log('Life---componentDidUpdate')
      }


      // 初始化渲染、状态更新之后
      render() {
        console.log('Life---render')
        const { count } = this.state
        return (
          <div>
            <h2>当前求和为：{count}</h2>
            <button onClick={this.add}>点我+1</button>
            <button onClick={this.death}>卸载组件</button>
            <button onClick={this.force}>强制刷新</button>
          </div>
        )
      }
    }

    class A extends React.Component {
      state = { carName: '宝马' }

      changeCar = () => {
        this.setState({ carName: '奥拓' })
      }
      render() {
        return (
          <div>
            <div>我是A组件</div>
            <button onClick={this.changeCar}>换车</button>
            <B carName={this.state.carName} />
          </div>
        )
      }
    }

    class B extends React.Component {
      // 组件将要接收新的props的钩子
      UNSAFE_componentWillReceiveProps(props) {
        console.log('B---componentWillReceiveProps', props)
      }

      //控制组件更新的“阀门”
      shouldComponentUpdate() {
        console.log('B---shouldComponentUpdate')
        return true
      }

      // 组件将要更新的钩子
      componentWillUpdate() {
        console.log('B---componentWillUpdate')
      }
      // 组件更新完毕的钩子
      componentDidUpdate() {
        console.log('B---componentDidUpdate')
      }
      render() {
        console.log('B---render')
        return (
          <div>
            <div>我是B组件，接收到的车是{this.props.carName}</div>
          </div>
        )
      }
    }
    // 2. 渲染虚拟组件到页面
    ReactDOM.render(<Life />, document.getElementById('test'))

  </script>
</body>

</html>